package edu.upb.acs.jobsmaps.activity;

import android.accounts.AccountManager;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.auth.GooglePlayServicesAvailabilityException;
import com.google.android.gms.auth.UserRecoverableAuthException;
import com.google.android.gms.common.AccountPicker;
import com.google.android.gms.common.GooglePlayServicesUtil;
import edu.upb.acs.jobsmaps.R;
import edu.upb.acs.jobsmaps.activity.login.GetGoogleUserDetailsTask;

public class LoginActivity extends Activity {
	private static final String TAG = "PlayHelloActivity";
	private static final String SCOPE = "oauth2:https://www.googleapis.com/auth/userinfo.profile";

	private TextView mOut;

	static final int REQUEST_CODE_PICK_ACCOUNT = 1000;
	static final int REQUEST_CODE_RECOVER_FROM_AUTH_ERROR = 1001;
	static final int REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR = 1002;

	private String mEmail;

	private Button loginButton;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.login);

		mOut = (TextView) findViewById(R.id.message);

		loginButton = (Button) findViewById(R.id.loginButton);

		loginButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View arg0) {
				Log.d(TAG, "*** Login user");
				getUsername();
				Log.d(TAG, "Done with this");
			}
		});
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (requestCode == REQUEST_CODE_PICK_ACCOUNT) {
			if (resultCode == RESULT_OK) {
				mEmail = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);

				Log.d(TAG, "** login for email = "+ mEmail);

				getUsername();
			} else if (resultCode == RESULT_CANCELED) {
				Toast.makeText(this, "You must pick an account", Toast.LENGTH_SHORT).show();
			}
		} else if ((requestCode == REQUEST_CODE_RECOVER_FROM_AUTH_ERROR ||
				requestCode == REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR)
				&& resultCode == RESULT_OK) {
			handleAuthorizeResult(resultCode, data);
			return;
		}
		super.onActivityResult(requestCode, resultCode, data);
	}

	private void handleAuthorizeResult(int resultCode, Intent data) {
		if (data == null) {
			show("Unknown error, click the button again");
			return;
		}
		if (resultCode == RESULT_OK) {
			Log.i(TAG, "Retrying");
			getTask(this, mEmail, SCOPE).execute();

			return;
		}
		if (resultCode == RESULT_CANCELED) {
			show("User rejected authorization.");
			return;
		}
		show("Unknown error, click the button again");
	}


	/** Attempt to get the user name. If the email address isn't known yet,
	 * then call pickUserAccount() method so the user can pick an account.
	 */
	private void getUsername() {
		if (mEmail == null) {
			Log.d(TAG, "Pick user account");
			pickUserAccount();
		} else {
			if (isDeviceOnline()) {
				Log.d(TAG, "Execute task to get user credentials");

				getTask(LoginActivity.this, mEmail, SCOPE).execute();
			} else {
				Toast.makeText(this, "No network connection available", Toast.LENGTH_SHORT).show();
			}
		}
	}



	/** Starts an activity in Google Play Services so the user can pick an account */
	private void pickUserAccount() {
		String[] accountTypes = new String[]{"com.google"};
		Intent intent = AccountPicker.newChooseAccountIntent(null, null,
				accountTypes, false, null, null, null, null);
		startActivityForResult(intent, REQUEST_CODE_PICK_ACCOUNT);
	}

	/** Checks whether the device currently has a network connection */
	private boolean isDeviceOnline() {
		ConnectivityManager connMgr = (ConnectivityManager)
				getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
		if (networkInfo != null && networkInfo.isConnected()) {
			return true;
		}
		return false;
	}


	/**
	 * This method is a hook for background threads and async tasks that need to update the UI.
	 * It does this by launching a runnable under the UI thread.
	 */
	public void show(final String message) {
		Log.d(TAG, "Display something");
		runOnUiThread(new Runnable() {
			@Override
			public void run() {
				mOut.setText(message);
			}
		});
	}

	/**
	 * This method is a hook for background threads and async tasks that need to provide the
	 * user a response UI when an exception occurs.
	 */
	public void handleException(final Exception e) {
		runOnUiThread(new Runnable() {
			@Override
			public void run() {
				if (e instanceof GooglePlayServicesAvailabilityException) {
					// The Google Play services APK is old, disabled, or not present.
					// Show a dialog created by Google Play services that allows
					// the user to update the APK
					int statusCode = ((GooglePlayServicesAvailabilityException)e)
							.getConnectionStatusCode();
					Dialog dialog = GooglePlayServicesUtil.getErrorDialog(statusCode,
							LoginActivity.this,
							REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR);
					dialog.show();
				} else if (e instanceof UserRecoverableAuthException) {
					// Unable to authenticate, such as when the user has not yet granted
					// the app access to the account, but the user can fix this.
					// Forward the user to an activity in Google Play services.
					Intent intent = ((UserRecoverableAuthException)e).getIntent();
					startActivityForResult(intent,
							REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR);
				}
			}
		});
	}

	/**
	 * Note: This approach is for demo purposes only. Clients would normally not get tokens in the
	 * background from a Foreground activity.
	 */
	private GetGoogleUserDetailsTask getTask(
			LoginActivity activity, String email, String scope) {
		GetGoogleUserDetailsTask task = new GetGoogleUserDetailsTask(activity, email, scope);
		return task;
	}

}
